home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / ipc / mainshmnserv.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  3KB  |  126 lines

  1. #include    <stdio.h>
  2. #include    <sys/types.h>
  3. #include    <sys/ipc.h>
  4. #include    <sys/shm.h>
  5.  
  6. #include    "shm.h"
  7.  
  8. int    clisem, servsem;    /* semaphore IDs */
  9.  
  10. int    shmid[NBUFF];        /* shared memory IDs */
  11. Mesg    *mesgptr[NBUFF];    /* ptr to message structures, which are
  12.                    in the shared memory segment */
  13.  
  14. main()
  15. {
  16.     register int    i;
  17.  
  18.     /*
  19.      * Get the shared memory segments and attach them.
  20.      */
  21.  
  22.     for (i = 0; i < NBUFF; i++) {
  23.         if ( (shmid[i] = shmget(SHMKEY + i, sizeof(Mesg),
  24.                         PERMS | IPC_CREAT)) < 0)
  25.             err_sys("server: can't get shared memory %d", i);
  26.         if ( (mesgptr[i] = (Mesg *) shmat(shmid[i], (char *) 0, 0))
  27.                             == (Mesg *) -1)
  28.             err_sys("server: can't attach shared memory %d", i);
  29.     }
  30.  
  31.     /*
  32.      * Create the two semaphores.
  33.      */
  34.  
  35.     if ( (clisem = sem_create(SEMKEY1, 1)) < 0)
  36.         err_sys("server: can't create client semaphore");
  37.     if ( (servsem = sem_create(SEMKEY2, 0)) < 0)
  38.         err_sys("server: can't create server semaphore");
  39.  
  40.     server();
  41.  
  42.     /*
  43.      * Detach the shared memory segments and close the semaphores.
  44.      * We let the client remove the shared memory segments,
  45.      * since it'll be the last one to use them.
  46.      */
  47.  
  48.     for (i = 0; i < NBUFF; i++) {
  49.         if (shmdt(mesgptr[i]) < 0)
  50.             err_sys("server: can't detach shared memory %d", i);
  51.     }
  52.  
  53.     sem_close(clisem);
  54.     sem_close(servsem);
  55.  
  56.     exit(0);
  57. }
  58.  
  59. server()
  60. {
  61.     register int    i, n, filefd;
  62.     char        errmesg[256], *sys_err_str();
  63.  
  64.     /*
  65.      * Wait for the client to write the filename into shared memory,
  66.      * then try to open the file.
  67.      */
  68.  
  69.     sem_wait(servsem);
  70.     mesgptr[0]->mesg_data[mesgptr[0]->mesg_len] = '\0';
  71.                     /* null terminate filename */
  72.     if ( (filefd = open(mesgptr[0]->mesg_data, 0)) < 0) {
  73.         /*
  74.          * Error.  Format an error message and send it back
  75.          * to the client.
  76.          */
  77.  
  78.         sprintf(errmesg, ": can't open, %s\n", sys_err_str());
  79.         strcat(mesgptr[0]->mesg_data, errmesg);
  80.         mesgptr[0]->mesg_len = strlen(mesgptr[0]->mesg_data);
  81.         sem_signal(clisem);    /* wake up client */
  82.  
  83.         sem_wait(servsem);    /* wait for client to process */
  84.         mesgptr[1]->mesg_len = 0;
  85.         sem_signal(clisem);    /* wake up client */
  86.  
  87.     } else {
  88.         /*
  89.          * Initialize the server semaphore to the number
  90.          * of buffers.  We know its value is 0 now, since
  91.          * it was initialized to 0, and the client has done a
  92.          * sem_signal(), followed by our sem_wait() above.
  93.          * What we do is increment the semaphore value
  94.          * once for every buffer (i.e., the number of resources
  95.          * that we have).
  96.          */
  97.  
  98.         for (i = 0; i < NBUFF; i++)
  99.             sem_signal(servsem);
  100.  
  101.         /*
  102.          * Read the data from the file right into shared memory.
  103.          * The -1 in the number-of-bytes-to-read is because some
  104.          * Unices have a bug if you try and read into the final byte
  105.          * of a shared memory segment.
  106.          */
  107.  
  108.         for ( ; ; ) {
  109.             for (i = 0; i < NBUFF; i++) {
  110.                 sem_wait(servsem);
  111.                 n = read(filefd, mesgptr[i]->mesg_data,
  112.                             MAXMESGDATA-1);
  113.                 if (n < 0)
  114.                     err_sys("server: read error");
  115.                 mesgptr[i]->mesg_len = n;
  116.                 sem_signal(clisem);
  117.                 if (n == 0)
  118.                     goto alldone;
  119.             }
  120.         }
  121. alldone:
  122.         /* we've already written the 0-length final buffer */
  123.         close(filefd);
  124.     }
  125. }
  126.